package cn.steel.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.steel.domain.entity.Cart;
import cn.steel.domain.entity.Product;
import cn.steel.domain.entity.User;
import cn.steel.domain.vo.CartVo;
import cn.steel.mapper.CartMapper;
import cn.steel.mapper.ProductMapper;
import cn.steel.mapper.UserMapper;
import cn.steel.service.CartService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class CartServiceImpl implements CartService {

    private final CartMapper cartMapper;
    private final ProductMapper productMapper;
    private final UserMapper userMapper;
    private final RedisTemplate<String, Object> redisTemplate;
    private final ObjectMapper objectMapper;
    private static final String CART_KEY_PREFIX = "cart:user:";

    private String getCartKey(Long userId) {
        return CART_KEY_PREFIX + userId;
    }

    @Override
    public List<CartVo> getCartByUserId(Long userId) {
        validateBuyer(userId);
        String cartKey = getCartKey(userId);
        List<CartVo> cachedCarts = (List<CartVo>) redisTemplate.opsForValue().get(cartKey);
        if (cachedCarts != null) {
            return cachedCarts;
        }

        List<Cart> carts = cartMapper.findByUserId(userId);
        List<CartVo> cartVos = carts.stream().map(cart -> {
            Product product = productMapper.findProductById(cart.getProductId());
            CartVo vo = new CartVo();
            BeanUtil.copyProperties(cart, vo);
            vo.setProductName(product.getName());
            vo.setProductImage(product.getImageUrl());
            vo.setPrice(product.getPrice());
            return vo;
        }).collect(Collectors.toList());

        redisTemplate.opsForValue().set(cartKey, cartVos, 1, TimeUnit.HOURS);
        return cartVos;
    }

    @Override
    @Transactional
    public void addToCart(Long userId, Long productId, Integer quantity) {
        validateBuyer(userId);
        Product product = productMapper.findProductById(productId);
        if (product == null) {
            throw new IllegalArgumentException("商品不存在");
        }
        Cart existingCart = cartMapper.findByUserIdAndProductId(userId, productId);
        if (existingCart != null) {
            cartMapper.updateByUserIdAndProductId(userId, productId, existingCart.getQuantity() + quantity);
        } else {
            Cart cart = new Cart();
            cart.setUserId(userId);
            cart.setProductId(productId);
            cart.setQuantity(quantity);
            cart.setPrice(product.getPrice());
            cart.setSelected(true);
            cart.setCreateTime(LocalDateTime.now());
            cart.setUpdateTime(LocalDateTime.now());
            cartMapper.insert(cart);
        }
        redisTemplate.delete(getCartKey(userId));
    }

    @Override
    @Transactional
    public void updateCart(Long userId, Long productId, Integer quantity) {
        validateBuyer(userId);
        if (quantity <= 0) {
            throw new IllegalArgumentException("数量必须大于0");
        }
        Cart existingCart = cartMapper.findByUserIdAndProductId(userId, productId);
        if (existingCart == null) {
            throw new IllegalArgumentException("购物车记录不存在");
        }
        cartMapper.updateByUserIdAndProductId(userId, productId, quantity);
        redisTemplate.delete(getCartKey(userId));
    }

//    @Override
//    @Transactional
//    public void removeFromCart(Long userId, Long productId) {
//        validateBuyer(userId);
//        cartMapper.deleteByUserIdAndProductId(userId, productId);
//        redisTemplate.delete(getCartKey(userId));
//    }

    @Override
    @Transactional
    public void clearCart(Long userId) {
        validateBuyer(userId);
        cartMapper.clearCartByUserId(userId);
        redisTemplate.delete(getCartKey(userId));
    }

    @Override
    @Transactional
    public void updateCartSelection(Long userId, Long productId, Boolean selected) {
        validateBuyer(userId);
        Cart existingCart = cartMapper.findByUserIdAndProductId(userId, productId);
        if (existingCart == null) {
            throw new IllegalArgumentException("购物车记录不存在");
        }
        cartMapper.updateSelectionByUserIdAndProductId(userId, productId, selected);
        redisTemplate.delete(getCartKey(userId));
    }

    @Override
    @Transactional
    public void selectAllCarts(Long userId, Boolean selected) {
        validateBuyer(userId);
        cartMapper.updateAllSelectionByUserId(userId, selected);
        redisTemplate.delete(getCartKey(userId));
    }

    @Override
    @Transactional
    public void deleteSelectedCarts(Long userId) {
        validateBuyer(userId);
        cartMapper.deleteSelectedByUserId(userId);
        redisTemplate.delete(getCartKey(userId));
    }

    private void validateBuyer(Long userId) {
        User user = userMapper.findUserById(userId);
        if (user == null) {
            throw new IllegalArgumentException("用户不存在");
        }
        if (!"BUYER".equals(user.getRole())) {
            throw new IllegalArgumentException("仅买家用户可以操作购物车");
        }
    }
}